package com.example.tass.controller;

import cn.tass.SRJ1933.devices.inf.TassSignServerApi;
import cn.tass.SRJ1933.devices.params.response.rawSign.RawSignExternalResponse;
import cn.tass.SRJ1933.devices.params.response.rawSign.RawSignResponse;
import cn.tass.SRJ1933.devices.params.response.rawSign.VerifyRawSignResponse;
import cn.tass.SRJ1933.devices.params.response.rawSign.VerifyRawsignExternalResponse;
import cn.tass.exceptions.TAException;
import com.example.tass.common.ResultMessage;
import com.example.tass.constant.Constants;
import com.example.tass.domain.MyRawSignExternalRequest;
import com.example.tass.domain.MyVerifyRawSignRequest;
import com.example.tass.domain.MyVerifyRawsignExternalRequest;
import com.example.tass.domain.SignRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * 3.2 裸签名
 */
@RestController
public class SimpleSignTest_3_2 {
    private static final Logger logger = LoggerFactory.getLogger(SimpleSignTest_3_2.class);
    private static String printFormat = "错误码[%d]\n错误消息[%s]\n接口结果： %s\n";

    // 初始化操作(连接上江南天安的SVSM服务器)
    private TassSignServerApi signServerApi;

    public SimpleSignTest_3_2(TassSignServerApi signServerApi) {
        this.signServerApi = signServerApi;
    }

    /**
     * 3.2.1.1 编制裸签名（内部密钥 – 部分参数）
     *
     * @param signRequest
     * @return
     */
    @GetMapping(value = "/rawSign")
    public ResultMessage rawSign(@RequestBody SignRequest signRequest) {
        try {
            RawSignResponse rawSignResponse = signServerApi.rawSign(signRequest.getKeyId(), signRequest.getKeyIdType(), signRequest.getKeyAccessCode(), signRequest.getData(), signRequest.getDataType());
            if (rawSignResponse.getCode() != 0) {
                logger.error(rawSignResponse.getMsg());
                return ResultMessage.newFailureResult(rawSignResponse.getMsg());
            } else {
                System.out.println("编制裸签名 - 内部密钥 - 部分参数： " + String.format(printFormat, rawSignResponse.getCode(), rawSignResponse.getMsg(), rawSignResponse.getSign()));
                return ResultMessage.newSuccessResult(rawSignResponse.getSign());
            }
        } catch (TAException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 3.2.1.2 编制裸签名（内部密钥 – 全部参数）
     *
     * @param signRequest 签名请求数据
     * @return 签名值
     */
    @GetMapping(value = "/rawSignAllParam")
    public ResultMessage rawSignAllParam(@RequestBody SignRequest signRequest) {
        try {
            RawSignResponse rawSignResponse = signServerApi.rawSign(signRequest.getKeyId(), signRequest.getKeyIdType(), signRequest.getAlgorithm(), signRequest.getSm2UserID(), signRequest.getRsaPadMode(),
                    signRequest.isCheckCert(), signRequest.getSignFormat(), signRequest.getKeyAccessCode(), signRequest.getData(), signRequest.getDataType());
            if (rawSignResponse.getCode() != 0) {
                logger.error(rawSignResponse.getMsg());
                return ResultMessage.newFailureResult(rawSignResponse.getMsg());
            } else {
                System.out.println("编制裸签名 - 内部密钥 - 全部参数： " + String.format(printFormat, rawSignResponse.getCode(), rawSignResponse.getMsg(), rawSignResponse.getSign()));
                return ResultMessage.newSuccessResult(rawSignResponse.getSign());
            }
        } catch (TAException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 3.2.2.1 验证裸签名（内部密钥 – 部分参数）
     *
     * @param myVerifyRawSignRequest
     * @return
     */
    @GetMapping(value = "/verifyRawSign")
    public ResultMessage verifyRawSign(@RequestBody MyVerifyRawSignRequest myVerifyRawSignRequest) {
        try {
            VerifyRawSignResponse verifyRawSignResponse = signServerApi.verifyRawSign(myVerifyRawSignRequest.getKeyOrCertId(),
                    myVerifyRawSignRequest.getKeyOrCertIdType(), myVerifyRawSignRequest.getData(), myVerifyRawSignRequest.getDataType(), myVerifyRawSignRequest.getSign());
            if (verifyRawSignResponse.getCode() != 0) {
                logger.error(verifyRawSignResponse.getMsg());
                return ResultMessage.newFailureResult(verifyRawSignResponse.getMsg());
            } else {
                System.out.println("验证裸签名 - 内部密钥 - 部分参数： " + String.format(printFormat, verifyRawSignResponse.getCode(), verifyRawSignResponse.getMsg(), verifyRawSignResponse.getPubKeyInfoType() + " " + verifyRawSignResponse.getPubKeyInfo()));
                return ResultMessage.newSuccessResult(Constants.VERIFY_SUCCESS);
            }
        } catch (TAException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 3.2.2.2 验证裸签名（内部密钥 – 全部参数）
     *
     * @param myVerifyRawSignRequest
     * @return
     */
    @GetMapping(value = "/verifyRawSignAllParam")
    public ResultMessage verifyRawSignAllParam(@RequestBody MyVerifyRawSignRequest myVerifyRawSignRequest) {
        try {
            VerifyRawSignResponse verifyRawSignResponse = signServerApi.verifyRawSign(myVerifyRawSignRequest.getKeyOrCertId(),
                    myVerifyRawSignRequest.getKeyOrCertIdType(), myVerifyRawSignRequest.getAlgorithm(), myVerifyRawSignRequest.getData(),
                    myVerifyRawSignRequest.getDataType(), myVerifyRawSignRequest.getSign(), myVerifyRawSignRequest.getSignFormat(), myVerifyRawSignRequest.getSm2UserID(),
                    myVerifyRawSignRequest.getRsaPadMode(), myVerifyRawSignRequest.getVerifyLevel(), myVerifyRawSignRequest.isReturnPubKeyInfo());
            if (verifyRawSignResponse.getCode() != 0) {
                logger.error(verifyRawSignResponse.getMsg());
                return ResultMessage.newFailureResult(verifyRawSignResponse.getMsg());
            } else {
                System.out.println("验证裸签名 - 内部密钥 - 全部参数： " + String.format(printFormat, verifyRawSignResponse.getCode(), verifyRawSignResponse.getMsg(), verifyRawSignResponse.getPubKeyInfoType() + " " + verifyRawSignResponse.getPubKeyInfo()));
                return ResultMessage.newSuccessResult(Constants.VERIFY_SUCCESS + ",验签使用的公钥是: " + verifyRawSignResponse.getPubKeyInfo());
            }
        } catch (TAException e) {
            throw new RuntimeException(e);
        }
    }

    // 3.2.3.1 编制裸签名（外部私钥明文）
    @GetMapping(value = "/rawSignExternal")
    public ResultMessage rawSignExternal(@RequestBody MyRawSignExternalRequest signExternalRequest) {
        try {
            RawSignExternalResponse rawSignExternalResponse = signServerApi.rawSignExternal(signExternalRequest.getPrivKey(), signExternalRequest.getData(), signExternalRequest.getDataType(),
                    signExternalRequest.getAlgorithm(), signExternalRequest.getSm2UserID(), signExternalRequest.getSm2PubKeyInfo(), signExternalRequest.getSm2PubKeyInfoType(),
                    signExternalRequest.getRsaPadMode(), signExternalRequest.getSignFormat());
            if (rawSignExternalResponse.getCode() != 0) {
                logger.error(rawSignExternalResponse.getMsg());
                return ResultMessage.newFailureResult(rawSignExternalResponse.getMsg());
            } else {
                System.out.println("编制裸签名 - 外部私钥明文： " + String.format(printFormat, rawSignExternalResponse.getCode(), rawSignExternalResponse.getMsg(), rawSignExternalResponse.getSign()));
                return ResultMessage.newSuccessResult(rawSignExternalResponse.getSign());
            }
        } catch (TAException e) {
            throw new RuntimeException(e);
        }
    }

    // 3.2.3.2 编制裸签名（外部私钥密文）
    @GetMapping(value = "/rawSignExternalEncKey")
    public ResultMessage rawSignExternalEncKey(@RequestBody MyRawSignExternalRequest request) {
        try {
            RawSignExternalResponse response = signServerApi.rawSignExternal(request.getPrivKey(), request.getEncKeyId(), request.getEnckeyAccessCode(), request.getEncMode(), request.getEncPadMode(),
                    request.getEncIv(), request.getData(), request.getDataType(), request.getAlgorithm(), request.getSm2UserID(), request.getSm2PubKeyInfo(),
                    request.getSm2PubKeyInfoType(), request.getRsaPadMode(), request.getSignFormat());
            if (response.getCode() != 0) {
                logger.error(response.getMsg());
                return ResultMessage.newFailureResult(response.getMsg());
            } else {
                System.out.println("编制裸签名 - 外部私钥明文： " + String.format(printFormat, response.getCode(), response.getMsg(), response.getSign()));
                return ResultMessage.newSuccessResult(response.getSign());
            }
        } catch (TAException e) {
            throw new RuntimeException(e);
        }
    }

    // 3.2.4 验证裸签名（外部公钥或证书）
    @GetMapping(value = "/verifyRawsignExternal")
    public ResultMessage verifyRawsignExternal(@RequestBody MyVerifyRawsignExternalRequest request) {
        try {
            VerifyRawsignExternalResponse response = signServerApi.verifyRawsignExternal(request.getPubKeyInfo(), request.getPubKeyInfoType(), request.getAlgorithm(), request.getData(),
                    request.getDataType(), request.getSign(), request.getSignFormat(), request.getSm2UserID(), request.getRsaPadMode(), request.getVerifyLevel());
            if (response.getCode() != 0) {
                logger.error(response.getMsg());
                return ResultMessage.newFailureResult(response.getMsg());
            } else {
                return ResultMessage.newSuccessResult(Constants.VERIFY_SUCCESS);
            }
        } catch (TAException e) {
            throw new RuntimeException(e);
        }
    }

}
